element-ui checkbox组件源码学习
来看下比较常用的,且和radio比较类似的checkbox组件。
一、html部分
整个html部分与radio比较类似,简单的来看下。
最外层时label,且有配置控制着border、disabled、整个checkbox的大小。
往内部是两个span,一个是checkbox前的勾选框,后一个span是checkbox后显示的文字。 第一个span中,class是el-checkbox__inner的span就是checkbox元素框的实现,而after伪元素则是配合实现选中状态的。后面两个input元素主要是为了当给定ture与false值时,需要给input加上true-value与false-value两个属性值。
后一个span则是放checkbox对应的勾选值的。默认是优先显示slot中的值的,如果没有,则显示当前checkbox的label值。
二、JS部分
按照属性看下,
name
名称
mixins
混入了事件的broadcast与dispatch事件传播机制。
inject
注入elForm与elFormItem对象,防止单用时取值出错。
componentName
组件名称。
data()
- selfModel,该组件的model值。
- focus,是否获取了焦点。
- isLimitExceeded,判断是否超出设置的最大最小值。
computed
- model,通过中转的方式代理当前值的获取与设置。
当我们获取model值时,
get() {
// 如果有checkbox group父组件,则直接使用store的值,否则
// 若本组件的value(model)值不为undefined,则返回,否则返回selfModel
return this.isGroup
? this.store : this.value !== undefined
? this.value : this.selfModel;
}
设置model的话,会有如下操作:
set(val) {
if (this.isGroup) {
// 当有group父级时,需要对值的范围做判断
this.isLimitExceeded = false;
// 当group有min值,且要set的值小于min时,将标志变量置为true
(this._checkboxGroup.min !== undefined &&
val.length < this._checkboxGroup.min &&
(this.isLimitExceeded = true));
// 当group有max值,且要set的值大于max时,将标志变量置为true
(this._checkboxGroup.max !== undefined &&
val.length > this._checkboxGroup.max &&
(this.isLimitExceeded = true));
// 没有出现设置值超出时,触发修改checkboxgroup的model值
this.isLimitExceeded === false &&
this.dispatch('ElCheckboxGroup', 'input', \[val\]);
} else {
// 没group时,直接修改本组件的model值和selfModel值
this.$emit('input', val);
this.selfModel = val;
}
}
- isChecked(),判断该checkbox是否已经被选中了。由于model值的类型比较多,所以需要较多的判断。
isChecked() {
if ({}.toString.call(this.model) === '\[object Boolean\]') {
// 如果是boolean类型的(checkbox的基本用法),直接返回就行
return this.model;
} else if (Array.isArray(this.model)) {
// model是数组时,判断下当前组件的label值是否在已选择值之中
return this.model.indexOf(this.label) > -1;
} else if (this.model !== null && this.model !== undefined) {
// 当trueLabel有自己的值时,需要与trueLabel校验
return this.model === this.trueLabel;
}
}
- isGroup(),是否是group,与radio的一样,向上逐层遍历。
- store(),用于获取当前的value(model)值。
- isDisabled(),判断当前组件是否时disabled状态。
disabled的优先级顺序,checkbox-group > 本身 > form。
- _elFormItemSize(),获取formitem的大小。
- checkboxSize(),checkbox大小。
props
- value,当前checkbox选中的值。
- label,该checkbox的值。
- indeterminate,设置 indeterminate 状态,只负责样式控制。
- disabled,组件是否禁用。
- checked,组件是否已经被选中。
- name,原生 name 属性,控制checkbox分组。
- trueLabel,选中时的值。
- falseLabel,没有选中时的值。
- id,当indeterminate为真时,为controls提供相关连的checkbox的id,表明元素间的控制关系。
- controls,当indeterminate为真时,为controls提供相关连的checkbox的id,表明元素间的控制关系。
- border,是否显示边框。
- size,大小,尺寸,控制图标,文字大小。
methods
- addToStore(),用于初始化值,并保存到model中。
addToStore() {
if (
Array.isArray(this.model) &&
this.model.indexOf(this.label) === -1
) {
// model是数组,且不包含当前label值时,进行添加处理
this.model.push(this.label);
} else {
// 直接修改
this.model = this.trueLabel || true;
}
}
- handleChange(ev),处理checkbox改变事件。
if (this.isLimitExceeded) return;
首先是对限制进行判断,不在范围内不操作。
if (ev.target.checked) {
value = this.trueLabel === undefined ? true : this.trueLabel;
} else {
value = this.falseLabel === undefined ? false : this.falseLabel;
}
当无trueLabel,falseLabel时,选中为true,否则false,有trueLabel或falseLabel值,则使用。
随后,处理一些change事件。
created()
当组件创建时,有被选中时,触发addToStore()方法。
mounted()
if (this.indeterminate) {
this.$el.setAttribute('aria-controls', this.controls);
}
为indeterminate元素 添加aria-controls 属性。
watch
- value(value)
this.dispatch('ElFormItem', 'el.form.change', value);
当前checkbox选中改变时,触发向上广播到formitem,触发el.form.change事件。
带注释的源码下载:checkbox.vue。